// Time:  O(1)
// Space: O(1)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

#include "head/ListNode.h"

#include <vector>
#include <iostream>
#include <cassert>
using namespace std;


class Solution {
public:
    void deleteNode(ListNode* node) {
        if(!node || !node->next) return;

        // if you don't have the head of the list
        // you can't change the previous node's next pointer
        // so you have to copy the value of the next node

        // A -> B -> C -> D
        // if you want to delete B
        // you can't change A's next pointer
        // so you have to copy C's value to B
        // and delete C
        // A -> C -> C -> D
        auto next = node->next;
        node->val = node->next->val;
        node->next = node->next->next;
        delete next;
    }
};

// Helper function to print the linked list
void printList(ListNode* head) {
    while (head) {
        std::cout << head->val << " ";
        head = head->next;
    }
    std::cout << std::endl;
}

// Helper function to create a linked list from a vector
ListNode* createList(const std::vector<int>& values) {
    if (values.empty()) return nullptr;
    ListNode* head = new ListNode(values[0]);
    ListNode* current = head;
    for (size_t i = 1; i < values.size(); ++i) {
        current->next = new ListNode(values[i]);
        current = current->next;
    }
    return head;
}

// Helper function to find a node with a specific value
ListNode* findNode(ListNode* head, int value) {
    while (head && head->val != value) {
        head = head->next;
    }
    return head;
}

int main() {
    Solution solution;

    // Test case 1: Delete node with value 3 from the list 1 -> 2 -> 3 -> 4 -> 5
    std::vector<int> values1 = {1, 2, 3, 4, 5};
    ListNode* head1 = createList(values1);
    ListNode* node1 = findNode(head1, 3);
    solution.deleteNode(node1);
    std::vector<int> expected1 = {1, 2, 4, 5};
    ListNode* current1 = head1;
    for (int val : expected1) {
        assert(current1->val == val);
        current1 = current1->next;
    }
    assert(current1 == nullptr);

    // Test case 2: Delete node with value 1 from the list 1 -> 2 -> 3
    std::vector<int> values2 = {1, 2, 3};
    ListNode* head2 = createList(values2);
    ListNode* node2 = findNode(head2, 1);
    solution.deleteNode(node2);
    std::vector<int> expected2 = {2, 3};
    ListNode* current2 = head2;
    for (int val : expected2) {
        assert(current2->val == val);
        current2 = current2->next;
    }
    assert(current2 == nullptr);

    // Test case 3: Delete node with value 2 from the list 1 -> 2 -> 3
    std::vector<int> values3 = {1, 2, 3};
    ListNode* head3 = createList(values3);
    ListNode* node3 = findNode(head3, 2);
    solution.deleteNode(node3);
    std::vector<int> expected3 = {1, 3};
    ListNode* current3 = head3;
    for (int val : expected3) {
        assert(current3->val == val);
        current3 = current3->next;
    }
    assert(current3 == nullptr);

    std::cout << "All tests passed!" << std::endl;

    return 0;
}